package com.zb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.constant.UserConstant;
import com.zb.excel.converter.WorkConverter;
import com.zb.entity.*;
import com.zb.exception.ZbException;
import com.zb.mapper.ZjFactoryMapper;
import com.zb.mapper.ZjWorkModuleMapper;
import com.zb.result.PageUtil;
import com.zb.secure.BCryptUtil;
import com.zb.service.*;
import com.zb.utils.TemplateReplaceUtil;
import com.zb.utils.ZbManager;
import com.zb.vo.WorkModuleDetailVo;
import com.zb.vo.WorkModuleListVo;
import com.zb.vo.WorkModuleSelectVo;
import com.zb.vo.WorkModuleVo;
import com.zb.yaml.EnDeSecret;
import com.zb.yaml.MobilePath;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 工单模块表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-09-13
 */
@Service
public class ZjWorkModuleServiceImpl extends ServiceImpl<ZjWorkModuleMapper, ZjWorkModule> implements ZjWorkModuleService {
    @Resource
    private ZjWorkModuleMapper workModuleMapper;
    @Resource
    private ZjWorkClientStrategyService workClientStrategyService;
    @Resource
    private ZjWorkSlaModuleService workSlaModuleService;
    @Autowired
    private ZjFactoryMapper zjFactoryMapper;


    // 新增或修改工单模块
    @Override
    @Transactional
    public void save(Long custAccId, WorkModuleVo workModuleVo) {
        Assert.isTrue(null == workModuleMapper.existByName(custAccId, workModuleVo.getId(), workModuleVo.getName()),"模块名称已重复：" + workModuleVo.getName());
        if (workModuleVo.getReservationTimeType() == 3) {
            Assert.isTrue(null != workModuleVo.getReservationStartTime() || null != workModuleVo.getReservationEndTime(),"预约时间类型为[时间范围]，预约时间区间不能为空！");
            if (!Objects.equals("00:00", DateFormatUtils.format(workModuleVo.getReservationEndTime(), "HH:mm"))) {
                Assert.isTrue(workModuleVo.getReservationEndTime().after(workModuleVo.getReservationStartTime()), "预约时间区间的结束时间必须大于开始时间");
            }
        }
        ZjWorkModule module = new ZjWorkModule();
        BeanUtils.copyProperties(workModuleVo, module);
        module.setDisabled(workModuleVo.getStatus());
        if (null != module.getId()) {
            this.updateById(module);
        } else {
            module.setId(IdWorker.getId());
            module.setCustAccId(custAccId);
            this.save(module);
        }
        workSlaModuleService.save(custAccId, module.getId(), workModuleVo.getWorkSlaId());
    }

    // 获取工单模块列表
    @Override
    public Map<String, Object> getList(Long custAccId, WorkModuleSelectVo selectVo) {
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_update");
        wrapper.eq("cust_acc_id", custAccId);
        if (null != selectVo.getType()) {
            wrapper.eq("type", selectVo.getType());
        }
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        PageUtil.setPageLimit(selectVo);
        Page<ZjWorkModule> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        List<ZjWorkClientStrategy> strategyList = new ArrayList<>();
        List<Long> workclientStragegyIds = page.getRecords().stream().filter(ZjWorkModule::getAutoDispatchClient).map(ZjWorkModule::getWorkClientStrategyId).distinct().toList();
        if (CollectionUtil.isNotEmpty(workclientStragegyIds)) {
            QueryWrapper<ZjWorkClientStrategy> clientStrategyQueryWrapper = new QueryWrapper<>();
            clientStrategyQueryWrapper.select("id", "name");
            clientStrategyQueryWrapper.in("id", workclientStragegyIds);
            strategyList.addAll(workClientStrategyService.list(clientStrategyQueryWrapper));
        }

        Map<String, String> paramMap = new HashMap<>();
        List<WorkModuleListVo> voList = page.getRecords().stream().map(module -> {
            WorkModuleListVo vo = new WorkModuleListVo();
            BeanUtils.copyProperties(module, vo);
            vo.setStatus(module.getDisabled());
            vo.setCreateTime(module.getGmtCreate());
            vo.setUpdateTime(module.getGmtUpdate());
            if (module.getAutoDispatchClient()) {
                vo.setWorkClientStrategy(strategyList.stream().filter(f -> Objects.equals(f.getId(), module.getWorkClientStrategyId())).map(ZjWorkClientStrategy::getName).findFirst().orElse(""));
            }
            try {
                paramMap.put(UserConstant.CUST_CODE, BCryptUtil.aesEncry(EnDeSecret.aesKey(),  custAccId.toString()));
                paramMap.put("type", vo.getType().toString());
                paramMap.put(UserConstant.MODULE_CODE, BCryptUtil.aesEncry(EnDeSecret.aesKey(),  vo.getId().toString()));
                vo.setPath(TemplateReplaceUtil.template(MobilePath.getOrderModule(), paramMap));
            } catch (ZbException e) {
                ZbManager.log.error("字符替换异常：" + e.getMessage());
            }
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }

    // 根据模块ID获取工单模块详情
    @Override
    public WorkModuleDetailVo getDetail(Long id) {
        ZjWorkModule module = this.getById(id);
        Assert.isTrue(null != module, "模块参数[" + id + "]的数据不存在");
        WorkModuleDetailVo vo = new WorkModuleDetailVo();
        BeanUtils.copyProperties(module, vo);
        vo.setStatus(module.getDisabled());
        ZjWorkSla workSla = workSlaModuleService.getSalNameByModuleId(id);
        if (null != workSla) {
            vo.setWorkSlaId(workSla.getId());
            vo.setSlaName(workSla.getName());
        }
        vo.setCreateTime(module.getGmtCreate());
        vo.setUpdateTime(module.getGmtUpdate());
        return vo;
    }

    // 根据模块ID批量启用或禁用模块
    @Override
    public void updateDisabledBatchById(List<Long> idList, boolean status) {
        workModuleMapper.updateDisabledBatchById(idList, status);
    }

    // 工单模块下拉列表查询
    @Override
    public Map<String, Object> workModulePageSelect(boolean mobile, Long custAccId, SelectVo selectVo) {
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("id", "type", "name", "is_overinsured AS overinsured", "warranty_day", "is_auto_dispatch_client AS autoDispatchClient",
                "is_auto_dispatch_network AS autoDispatchNetwork", "collect_customer_goods_price");
        wrapper.eq("cust_acc_id", custAccId).eq("is_disabled", false);
        wrapper.orderByDesc("gmt_update");
        if (mobile) {
            wrapper.eq("is_mobile_create_order_show", true);
        }
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        PageUtil.setSelectPageLimit(selectVo);
        Page<ZjWorkModule> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        List<OrderModuleSelectVo> voList = page.getRecords().stream().map(module -> {
            return new OrderModuleSelectVo(module.getId(), module.getName())
                    .setType(module.getType())
                    .setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice())
                    .setWarrantyDay( module.getWarrantyDay())
                    .setOverinsured(module.getOverinsured())
                    .setAutoDispatchClient(module.getAutoDispatchClient())
                    .setAutoDispatchNetwork(module.getAutoDispatchNetwork())
                    ;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getPages(), page.getTotal(), voList);
    }

    /**
     * 根据商家id查工单模块下拉列表
     * @param factoryId 商家ID
     * @return
     */
    public Map<String, Object> workModulePageSelect(Long factoryId) {
        Page<ZjWorkModule> page = zjFactoryMapper.getCustAccModuleInfo(new Page<>(-1, -1), factoryId);
        List<OrderModuleSelectVo> voList = page.getRecords().stream().map(module -> new OrderModuleSelectVo(module.getId(), module.getName())
                .setType(module.getType())
                .setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice())
                .setWarrantyDay( module.getWarrantyDay())
                .setOverinsured(module.getOverinsured())
                .setAutoDispatchClient(module.getAutoDispatchClient())
                .setAutoDispatchNetwork(module.getAutoDispatchNetwork())).toList();
        return PageUtil.pageList(page.getCurrent(), page.getPages(), page.getTotal(), voList);
    }

    // 根据ID集合获取部分模块信息
    @Override
    public List<ZjWorkModule> getPartInfoByIds(List<Long> ids) {
        if (CollectionUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name", "type");
        wrapper.in("id", ids);
        return this.list(wrapper);
    }

    // 根据ID集合获取部分模块信息
    @Override
    public ZjWorkModule getPartInfoById(Long id) {
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("id", "name", "type")
                .eq("id", id)
                .last("LIMIT 1");
        return this.getOne(wrapper);
    }

    // 根据客服分配策略ID获取关联的模块名称
    @Override
    public List<ZjWorkModule> getByWorkClientStrategyId(List<Long> workClientStrategyIds) {
        if (null == workClientStrategyIds || workClientStrategyIds.isEmpty()) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("name");
        wrapper.eq("work_client_strategy_id", workClientStrategyIds);
        return this.list(wrapper);
    }

    // 获取所有报单模块下拉列表
    @Override
    public List<OrderModuleSelectVo> getOrderModuleListSelect(Long custAccId, Long factoryId) {
        if (null != factoryId && factoryId > 0) {
            List<ZjWorkModule> moduleList = workModuleMapper.getOrderModuleListSelect(custAccId, factoryId);
            return moduleList.stream().map(module -> {
                return new OrderModuleSelectVo(module.getId(), module.getName())
                        .setType(module.getType())
                        .setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice())
                        .setWarrantyDay(module.getWarrantyDay())
                        .setOverinsured(module.getOverinsured())
                        .setAutoDispatchClient(module.getAutoDispatchClient())
                        .setAutoDispatchNetwork(module.getAutoDispatchNetwork())
                        ;
            }).toList();
        }
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("id", "type", "name", "is_overinsured AS overinsured", "warranty_day", "is_auto_dispatch_client AS autoDispatchClient",
                "is_auto_dispatch_network AS autoDispatchNetwork", "collect_customer_goods_price");
        wrapper.eq("cust_acc_id", custAccId)
                .eq("is_disabled", false);
        wrapper.orderByDesc("gmt_update");
        wrapper.eq("is_mobile_create_order_show", true);
        return this.list(wrapper).stream().map(module -> {
            return new OrderModuleSelectVo(module.getId(), module.getName())
                    .setType(module.getType())
                    .setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice())
                    .setWarrantyDay(module.getWarrantyDay())
                    .setOverinsured(module.getOverinsured())
                    .setAutoDispatchClient(module.getAutoDispatchClient())
                    .setAutoDispatchNetwork(module.getAutoDispatchNetwork())
                    ;
        }).toList();
    }

    // 根据模块ID获取模块详情
    @Override
    public OrderModuleSelectVo getMobileOrderModule(Long id) {
        ZjWorkModule module = this.getById(id);
        Assert.notNull(module, "模块数据不存在");
        return new OrderModuleSelectVo(module.getId(), module.getName())
                .setType(module.getType())
                .setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice())
                .setWarrantyDay(module.getWarrantyDay())
                .setOverinsured(module.getOverinsured())
                .setAutoDispatchClient(module.getAutoDispatchClient())
                .setAutoDispatchNetwork(module.getAutoDispatchNetwork())
                ;
    }

    // 工单模块带费用下拉列表查询
    @Override
    public Map<String, Object> workModulePricePageSelect(Long custAccId, SelectVo selectVo) {
        PageUtil.setSelectPageLimit(selectVo);
        QueryWrapper<ZjWorkModule> wrapper = new QueryWrapper<>();
        wrapper.select("id", "type", "name", "out_sourcing_price",  "collect_customer_goods_price")
                .eq("cust_acc_id", custAccId)
                .eq("is_disabled", false)
                .orderByDesc("gmt_update");
        if (StringUtils.isNotBlank(selectVo.getName())) {
            wrapper.like("name", selectVo.getName());
        }
        Page<ZjWorkModule> page = this.page(new Page<>(selectVo.getPage(), selectVo.getLimit()), wrapper);
        return PageUtil.pageList(page.getCurrent(), page.getPages(), page.getTotal(), page.getRecords().stream().map(module -> {
            OrderModulePriceSelectVo vo = new OrderModulePriceSelectVo();
            vo.setId(module.getId());
            vo.setName(module.getName());
            vo.setType(module.getType());
            vo.setPrice(module.getOutSourcingPrice());
            vo.setCollectCustomerGoodsPrice(module.getCollectCustomerGoodsPrice());
            return vo;
        }).toList());
    }
}
